home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 1.toast / Sample Code / Contributed / SpriteWorld / SpriteWorld Files / Sources / SpriteFrame.c < prev    next >
Encoding:
Text File  |  2000-10-06  |  36.4 KB  |  1,400 lines  |  [TEXT/CWIE]

  1. ///--------------------------------------------------------------------------------------
  2. //    SpriteFrame.c
  3. //
  4. //    Portions are copyright: © 1991-94 Tony Myles, All rights reserved worldwide.
  5. //
  6. //    Description:    implementation of the frame stuff
  7. ///--------------------------------------------------------------------------------------
  8.  
  9. #ifndef __TOOLUTILS__
  10. #include <ToolUtils.h>
  11. #endif
  12.  
  13. #ifndef __MEMORY__
  14. #include <Memory.h>
  15. #endif
  16.  
  17. #ifndef __RESOURCES__
  18. #include <Resources.h>
  19. #endif
  20.  
  21. #ifndef __ERRORS__
  22. #include <Errors.h>
  23. #endif
  24.  
  25. #ifndef __SWCOMMON__
  26. #include <SWCommonHeaders.h>
  27. #endif
  28.  
  29. #ifndef __SPRITEWORLDUTILS__
  30. #include <SpriteWorldUtils.h>
  31. #endif
  32.  
  33. #ifndef __SPRITECOMPILER__
  34. #include <SpriteCompiler.h>
  35. #endif
  36.  
  37. #ifndef __SPRITEFRAME__
  38. #include <SpriteFrame.h>
  39. #endif
  40.  
  41.  
  42. ///--------------------------------------------------------------------------------------
  43. //    SWCreateFrame
  44. ///--------------------------------------------------------------------------------------
  45.  
  46. SW_FUNC OSErr SWCreateFrame(
  47.     GDHandle theGDH,
  48.     FramePtr* newFrameP,
  49.     Rect* frameRect,
  50.     short depth,
  51.     Boolean createGWorld)
  52. {
  53.     OSErr             err = noErr;
  54.     GWorldPtr        frameGWorld;
  55.     FramePtr         tempFrameP;
  56.     long             numScanLines;    
  57.     
  58.     SW_ASSERT(theGDH != NULL);
  59.     SW_ASSERT(frameRect->top >= 0 && frameRect->left >= 0 &&
  60.             frameRect->right > frameRect->left && frameRect->bottom > frameRect->top);
  61.     
  62.     *newFrameP = NULL;
  63.     
  64.     numScanLines = frameRect->bottom - frameRect->top;
  65.     
  66.     tempFrameP = (FramePtr)NewPtrClear((Size)sizeof(FrameRec) + 
  67.         (sizeof(unsigned long) * (numScanLines+1)));
  68.     
  69.     if (tempFrameP != NULL)
  70.     {
  71.             // note: frame rect & depth must always be set, even if no frame GWorld exists
  72.         tempFrameP->frameRect = *frameRect;    
  73.         tempFrameP->frameDepth = depth;
  74.         tempFrameP->numScanLines = numScanLines;
  75.         SW_SET_RECT(tempFrameP->collisionInset, 0, 0, 0, 0);
  76.         tempFrameP->usesCollisionInset = false;
  77.         
  78.         if ( createGWorld )
  79.         {
  80.             if ( SWGetPixBitDepth((**theGDH).gdPMap) == depth )
  81.                 err = NewGWorld( &frameGWorld, depth, frameRect, nil, theGDH, noNewDevice );
  82.             else
  83.                 err = NewGWorld( &frameGWorld, depth, frameRect, nil, nil, (GWorldFlags)nil );
  84.             
  85.             if (err == noErr)
  86.             {
  87.                 tempFrameP->framePort = frameGWorld;
  88.                 tempFrameP->frameDevice = GetGWorldDevice( frameGWorld );
  89.                 tempFrameP->framePixHndl = GetGWorldPixMap( frameGWorld );
  90.             
  91.                 SWInitializeFrame( tempFrameP );
  92.             }
  93.         }
  94.         else
  95.         {
  96.             tempFrameP->framePort = NULL;
  97.             tempFrameP->frameDevice = NULL;
  98.             tempFrameP->framePixHndl = NULL;
  99.             err = noErr;
  100.         }
  101.         
  102.         if ( err == noErr )
  103.         {
  104.             tempFrameP->hotSpotH = 0;
  105.             tempFrameP->hotSpotV = 0;
  106.             tempFrameP->tileMaskIsSolid = false;
  107.             tempFrameP->sharesGWorld = false;
  108.             tempFrameP->isFrameLocked = false;
  109.             tempFrameP->isWindowFrame = false;
  110.             tempFrameP->interlacingIsOn = false;
  111.             tempFrameP->skipOddLines = true;
  112.     
  113.             tempFrameP->rleDataH = NULL;
  114.             tempFrameP->rleTokenStart = NULL;
  115.         #if SW_68K
  116.             tempFrameP->pixCodeH = NULL;
  117.             tempFrameP->frameBlitterP = NULL;
  118.         #endif
  119.             
  120.                 // the useCount keeps track of the number of sprites that
  121.                 // are using this frame. we need to know this so we don't
  122.                 // dispose this frame twice when we are disposing the 
  123.                 // sprites that use it.
  124.             tempFrameP->useCount = 0;
  125.                 
  126.             *newFrameP = tempFrameP;
  127.         }
  128.         
  129.     }
  130.     else
  131.     {
  132.         err = MemError();
  133.     }
  134.  
  135.     if (err != noErr)
  136.     {
  137.         if (tempFrameP != NULL)
  138.         {
  139.             if (tempFrameP->framePort != NULL)
  140.                 DisposeGWorld(tempFrameP->framePort);
  141.             DisposePtr((Ptr)tempFrameP);
  142.         }
  143.     }
  144.     
  145.     SWSetStickyIfError( err );
  146.     return err;
  147. }
  148.  
  149.  
  150. ///--------------------------------------------------------------------------------------
  151. //    SWCreateWindowFrame
  152. ///--------------------------------------------------------------------------------------
  153.  
  154. SW_FUNC OSErr SWCreateWindowFrame(
  155.     CWindowPtr    srcWindowP,
  156.     FramePtr*     newFrameP,
  157.     Rect*         frameRect,
  158.     short        maxHeight)
  159. {
  160.     OSErr             err = noErr;
  161.     FramePtr         tempFrameP = NULL;
  162.     long             numScanLines;
  163.     
  164.     SW_ASSERT(frameRect->top >= 0 && frameRect->left >= 0);
  165.     SW_ASSERT(frameRect->right > frameRect->left && frameRect->bottom > frameRect->top);
  166.     
  167.     *newFrameP = NULL;
  168.     
  169.         // more scanlines than we need, but this allows us to
  170.          // make the window larger later without having to dispose
  171.           // and re-create the WindowFrame.
  172.     numScanLines = (srcWindowP->portRect.bottom - srcWindowP->portRect.top);
  173.     numScanLines = SW_MAX(numScanLines, maxHeight);
  174.     
  175.         // Clip frameRect with the window's boundaries
  176.     frameRect->top = SW_MAX(frameRect->top, srcWindowP->portRect.top);
  177.     frameRect->left = SW_MAX(frameRect->left, srcWindowP->portRect.left);
  178.     frameRect->bottom = SW_MIN(frameRect->bottom, srcWindowP->portRect.bottom);
  179.     frameRect->right = SW_MIN(frameRect->right, srcWindowP->portRect.right);
  180.     
  181.     tempFrameP = (FramePtr)NewPtrClear((Size)sizeof(FrameRec) + 
  182.             (sizeof(unsigned long) * numScanLines));
  183.  
  184.     if (tempFrameP != NULL)
  185.     {
  186.         tempFrameP->framePort = srcWindowP;
  187.         tempFrameP->frameDevice = GetMainDevice();
  188.         tempFrameP->framePixHndl = srcWindowP->portPixMap;
  189.         tempFrameP->frameDepth = SWGetPixBitDepth( srcWindowP->portPixMap );
  190.         tempFrameP->frameRect = *frameRect;
  191.         tempFrameP->numScanLines = numScanLines;
  192.         tempFrameP->sharesGWorld = false;
  193.         tempFrameP->isWindowFrame = true;
  194.         tempFrameP->isFrameLocked = false;
  195.         tempFrameP->interlacingIsOn = false;
  196.         tempFrameP->skipOddLines = true;
  197.         
  198.         SWInitializeFrame( tempFrameP );
  199.         
  200.         *newFrameP = tempFrameP;
  201.     }
  202.     else
  203.     {
  204.         err = MemError();
  205.     }
  206.  
  207.     if (err != noErr)
  208.     {
  209.         if (tempFrameP != NULL)
  210.         {
  211.             DisposePtr((Ptr)tempFrameP);
  212.         }
  213.     }
  214.     
  215.     SWSetStickyIfError( err );
  216.     return err;
  217. }
  218.  
  219.  
  220. ///--------------------------------------------------------------------------------------
  221. //    SWCreateFrameFromCicnResource
  222. ///--------------------------------------------------------------------------------------
  223.  
  224. SW_FUNC OSErr SWCreateFrameFromCicnResource(
  225.     SpriteWorldPtr destSpriteWorld,
  226.     FramePtr* newFrameP,
  227.     short iconResID,
  228.     MaskType maskType)
  229. {
  230.     OSErr             err;  
  231.     GWorldPtr         saveGWorld;
  232.     GDHandle         saveGDH;
  233.     GDHandle        theGDH;
  234.     FramePtr         tempFrameP;
  235.     CIconHandle     cIconH;
  236.     RgnHandle         maskRgn;
  237.     Rect             frameRect;
  238.  
  239.     *newFrameP = NULL;
  240.     tempFrameP = NULL;
  241.     
  242.     SW_ASSERT(destSpriteWorld != NULL);
  243.  
  244.     GetGWorld(&saveGWorld, &saveGDH);
  245.     
  246.     cIconH = GetCIcon( iconResID );
  247.  
  248.     if (cIconH != NULL)
  249.     {
  250.         HNoPurge((Handle)cIconH);
  251.         frameRect = (**cIconH).iconPMap.bounds;
  252.         
  253.         theGDH = destSpriteWorld->mainSWGDH;
  254.         
  255.         err = SWCreateFrame(theGDH, &tempFrameP, &frameRect, destSpriteWorld->pixelDepth, kCreateGWorld);
  256.     }
  257.     else
  258.     {
  259.         err = MemError();
  260.         if ( err == noErr )
  261.             err = resNotFound;
  262.     }
  263.     
  264.     if (err == noErr)
  265.     {
  266.         (void)LockPixels( tempFrameP->framePixHndl );
  267.         SetGWorld(tempFrameP->framePort, nil);
  268.         EraseRect( &frameRect );
  269.         PlotCIcon(&frameRect, cIconH);
  270.         UnlockPixels( tempFrameP->framePixHndl );
  271.  
  272.             // make a region mask
  273.         if ((maskType & kRegionMask) != 0)
  274.         {
  275.             err = SWCreateRegionFromCIconMask(&maskRgn, cIconH);
  276.  
  277.             if (err == noErr)
  278.             {
  279.                 SWSetFrameMaskRgn(tempFrameP, maskRgn);
  280.             }
  281.         }
  282.     }
  283.     
  284.     if (err == noErr)
  285.     {
  286.             // make a pixel mask
  287.         if ((maskType & kPixelMask) != 0)
  288.         {
  289.                 // This is just like loading a mask PICT for a Sprite created from a PICT.
  290.             err = SWCreateGWorldFromCIconMask(destSpriteWorld, &tempFrameP->maskPort, cIconH);
  291.             
  292.             if (err == noErr)
  293.             {
  294.                 tempFrameP->maskDevice = GetGWorldDevice( tempFrameP->maskPort );
  295.                 tempFrameP->maskPixHndl = GetGWorldPixMap( tempFrameP->maskPort );
  296.             
  297.                     // This fixes the image GWorld so it works properly with 16-bit and 32-bit
  298.                     // blitters. Otherwise, a partial-mask blitter would be needed.
  299.                 SWFixImageGWorld( tempFrameP->framePort, tempFrameP->maskPort, (RectPtr) NULL );
  300.             }
  301.             
  302.                 // Invert the maskPort if in 8-bits or less. (Not necessary if we create the mask
  303.                 // using SWCreatePixelMaskFromGWorld.)
  304.             if (err == noErr && destSpriteWorld->pixelDepth <= 8)
  305.             {
  306.                 SWInvertGWorld(tempFrameP->maskPort);
  307.             }
  308.         }
  309.     }
  310.  
  311.     if (cIconH != NULL)
  312.     {
  313.         DisposeCIcon(cIconH);
  314.     }
  315.  
  316.     if (err == noErr)
  317.     {
  318.         *newFrameP = tempFrameP;
  319.     }
  320.  
  321.     if (err != noErr)
  322.     {
  323.             // an error occurred so dispose of anything we managed to create
  324.         if (tempFrameP != NULL)
  325.         {
  326.             SWDisposeFrame(&tempFrameP);
  327.         }
  328.     }
  329.  
  330.     SetGWorld(saveGWorld, nil);
  331.  
  332.     SWSetStickyIfError( err );
  333.     return err;
  334. }
  335.  
  336. ///--------------------------------------------------------------------------------------
  337. //    SWCreateFrameFromPictResource - currently only called by SWCreateSpriteFromPictResource.
  338. ///--------------------------------------------------------------------------------------
  339.  
  340. SW_FUNC OSErr SWCreateFrameFromPictResource(
  341.     SpriteWorldPtr destSpriteWorldP,
  342.     FramePtr* newFrameP,
  343.     short pictResID,
  344.     short maskResID,
  345.     MaskType maskType)
  346. {
  347.     OSErr             err;
  348.     GWorldPtr         saveGWorld,
  349.                     tempMaskGWorldP;
  350.     GDHandle         saveGDH;
  351.     GDHandle        theGDH;
  352.     PicHandle         spritePictH;
  353.     FramePtr         tempFrameP;
  354.     RgnHandle         maskRgn;
  355.     Rect             frameRect;
  356.     Boolean            needToInvertMask;
  357.  
  358.     SW_ASSERT(destSpriteWorldP != NULL);
  359.  
  360.     tempFrameP = NULL;
  361.     *newFrameP = NULL;
  362.     tempMaskGWorldP = NULL;
  363.     needToInvertMask = true;
  364.     
  365.     GetGWorld(&saveGWorld, &saveGDH);
  366.  
  367.     spritePictH = GetPicture(pictResID);
  368.  
  369.     if (spritePictH != NULL)
  370.     {
  371.         frameRect = (**spritePictH).picFrame;
  372.         OffsetRect( &frameRect, -frameRect.left, -frameRect.top );
  373.  
  374.         theGDH = destSpriteWorldP->mainSWGDH;
  375.         
  376.         err = SWCreateFrame(theGDH, &tempFrameP, &frameRect, destSpriteWorldP->pixelDepth, kCreateGWorld);
  377.  
  378.         if (err == noErr)
  379.         {
  380.             (void)LockPixels( tempFrameP->framePixHndl );
  381.             SetGWorld(tempFrameP->framePort, nil);
  382.             EraseRect(&frameRect);    // Necessary for some wierd PICT resource formats, like XOr
  383.             DrawPicture(spritePictH, &frameRect);
  384.             UnlockPixels( tempFrameP->framePixHndl );
  385.             ReleaseResource((Handle)spritePictH);
  386.         }
  387.         
  388.         if ( err == noErr && maskType != kNoMask )
  389.         {
  390.                 // Create the GWorld used to hold the mask.
  391.             err = SWCreateGWorldFromPictResource(destSpriteWorldP, &tempMaskGWorldP, maskResID);
  392.             
  393.             if (err == noErr)
  394.             {
  395.                     // If this is a self-masking Sprite, create the mask based on the image.
  396.                 if ( pictResID == maskResID && tempMaskGWorldP != NULL )
  397.                 {
  398.                     err = SWCreatePixelMaskFromGWorld( tempFrameP->framePort, tempMaskGWorldP, (RectPtr) NULL );
  399.                     needToInvertMask = false;
  400.                     
  401.                         // If the depth is 8-bits or less, and we need to create a region mask,
  402.                         // invert the maskGWorld so the region mask is created correctly.
  403.                     if (destSpriteWorldP->pixelDepth <= 8 && (maskType & kRegionMask) != 0 )
  404.                     {
  405.                         SWInvertGWorld(tempMaskGWorldP);
  406.                         needToInvertMask = true;
  407.                     }
  408.                 }
  409.                 else if ( (maskType & kPixelMask) != 0 )
  410.                 {
  411.                         // For Sprites that are not self-masking and have a pixel mask, we
  412.                         // should still fix the GWorld's image, in case SWTransparentColor
  413.                         // is not white, or in case the depth is 16-bits or above.
  414.                     SWFixImageGWorld( tempFrameP->framePort, tempMaskGWorldP, (RectPtr) NULL );
  415.                 }
  416.             }
  417.         }
  418.  
  419.             // make a region mask
  420.         if (((maskType & kRegionMask) != 0) && (err == noErr))
  421.         {
  422.             err = SWCreateRegionFromGWorldAndRect( &maskRgn,
  423.                 tempMaskGWorldP, &tempFrameP->frameRect );
  424.             
  425.             if (err == noErr)
  426.             {
  427.                 SWSetFrameMaskRgn(tempFrameP, maskRgn);
  428.             }
  429.         }
  430.         
  431.         if (err == noErr)
  432.         {
  433.                 // If a pixel mask is wanted, fix the tempMaskGWorld 
  434.                 // if the depth is 8-bits or less.
  435.             if ((maskType & kPixelMask) != 0)
  436.             {
  437.                 if (destSpriteWorldP->pixelDepth <= 8 && needToInvertMask)
  438.                 {
  439.                     SWInvertGWorld(tempMaskGWorldP);
  440.                 }
  441.             }        // If no pixel Mask wanted, dispose of the
  442.             else    // GWorld we used to make the region mask.
  443.             {
  444.                 if (tempMaskGWorldP != NULL)
  445.                 {
  446.                     DisposeGWorld( tempMaskGWorldP );
  447.                     tempMaskGWorldP = NULL;
  448.                 }
  449.             }
  450.             
  451.             if ( tempMaskGWorldP != NULL )
  452.             {
  453.                 tempFrameP->maskPort = tempMaskGWorldP;
  454.                 tempFrameP->maskDevice = GetGWorldDevice( tempFrameP->maskPort );
  455.                 tempFrameP->maskPixHndl = GetGWorldPixMap( tempFrameP->maskPort );
  456.             }
  457.             else
  458.             {
  459.                 tempFrameP->maskPort = NULL;
  460.                 tempFrameP->maskDevice = NULL;
  461.                 tempFrameP->maskPixHndl = NULL;
  462.             }
  463.         }
  464.  
  465.         if (err == noErr)
  466.         {
  467.             *newFrameP = tempFrameP;
  468.         }
  469.         else
  470.         {
  471.                 // an error occurred so dispose of anything we managed to create
  472.             if (tempFrameP != NULL)
  473.             {
  474.                 SWDisposeFrame(&tempFrameP);
  475.             }
  476.         }
  477.     }
  478.     else
  479.     {
  480.         err = MemError();
  481.         if ( err == noErr )
  482.             err = resNotFound;
  483.     }
  484.  
  485.     SetGWorld(saveGWorld, nil);
  486.  
  487.     SWSetStickyIfError( err );
  488.     return err;
  489. }
  490.  
  491.  
  492. ///--------------------------------------------------------------------------------------
  493. //    SWCreateFrameFromGWorldAndRect
  494. ///--------------------------------------------------------------------------------------
  495.  
  496. SW_FUNC OSErr SWCreateFrameFromGWorldAndRect(
  497.     FramePtr* newFrameP,
  498.     GWorldPtr pictGWorld,
  499.     GWorldPtr maskGWorld,
  500.     Rect* frameRect,
  501.     MaskType maskType)
  502. {
  503.     OSErr err;
  504.     GWorldPtr tempMaskGWorld;
  505.     
  506.     err = SWCreateFrameFromGWorldAndRectStart( &tempMaskGWorld, 
  507.             frameRect->right - frameRect->left, frameRect->bottom - frameRect->top, maskType );
  508.             
  509.     if ( err == noErr )
  510.     {
  511.         err = SWCreateFrameFromGWorldAndRectPartial( newFrameP, pictGWorld, maskGWorld, 
  512.                 tempMaskGWorld, frameRect, maskType );
  513.         
  514.         SWCreateFrameFromGWorldAndRectFinish( tempMaskGWorld );
  515.     }
  516.     
  517.     SWSetStickyIfError( err );
  518.     return err;
  519. }
  520.  
  521. ///--------------------------------------------------------------------------------------
  522. //    SWCreateFrameFromGWorldAndRectStart
  523. ///--------------------------------------------------------------------------------------
  524.  
  525. SW_FUNC OSErr SWCreateFrameFromGWorldAndRectStart(
  526.     GWorldPtr *tempMaskGWorld,
  527.     short maxWidth,
  528.     short maxHeight,
  529.     MaskType maskType)
  530. {
  531.     OSErr        err = noErr;
  532.     
  533.     *tempMaskGWorld = NULL;
  534.     if ((maskType & kRegionMask) != 0)
  535.     {
  536.         err = SWCreateRegionFromGWorldAndRectStart( tempMaskGWorld, maxWidth, maxHeight );
  537.     }
  538.     return err;
  539. }
  540.  
  541. ///--------------------------------------------------------------------------------------
  542. //    SWCreateFrameFromGWorldAndRectFinish
  543. ///--------------------------------------------------------------------------------------
  544.  
  545. SW_FUNC void SWCreateFrameFromGWorldAndRectFinish(
  546.     GWorldPtr tempMaskGWorld)
  547. {
  548.     SWCreateRegionFromGWorldAndRectFinish( tempMaskGWorld );
  549. }
  550.  
  551. ///--------------------------------------------------------------------------------------
  552. //    SWCreateFrameFromGWorldAndRectPartial
  553. ///--------------------------------------------------------------------------------------
  554.  
  555. SW_FUNC OSErr SWCreateFrameFromGWorldAndRectPartial(
  556.     FramePtr* newFrameP,
  557.     GWorldPtr pictGWorld,
  558.     GWorldPtr maskGWorld,
  559.     GWorldPtr tempMaskGWorld,
  560.     Rect* frameRect,
  561.     MaskType maskType)
  562. {
  563.     OSErr             err = noErr;
  564.     short            depth;
  565.     long             numScanLines;
  566.     FramePtr         tempFrameP;
  567.     RgnHandle         maskRgn;
  568.  
  569.     SW_ASSERT(pictGWorld != NULL);
  570.     SW_ASSERT(frameRect->top >= 0 && frameRect->left >= 0 &&
  571.               frameRect->right > frameRect->left && frameRect->bottom > frameRect->top);
  572.  
  573.     tempFrameP = NULL;
  574.     *newFrameP = NULL;
  575.  
  576.     numScanLines = frameRect->bottom - frameRect->top;
  577.     depth = SWGetPixBitDepth( GetGWorldPixMap(pictGWorld) );
  578.     
  579.     tempFrameP = (FramePtr)NewPtrClear((Size)sizeof(FrameRec) + 
  580.         (sizeof(unsigned long) * (numScanLines+1)));
  581.     
  582.     if (tempFrameP != NULL)
  583.     {
  584.         tempFrameP->framePort = pictGWorld;
  585.         tempFrameP->frameDevice = GetGWorldDevice( pictGWorld );
  586.         tempFrameP->framePixHndl = GetGWorldPixMap( pictGWorld );
  587.         tempFrameP->frameDepth = depth;
  588.             
  589.             // make a pixel mask
  590.         if ((maskType & kPixelMask) != 0) 
  591.         {
  592.             SW_ASSERT(maskGWorld != NULL);
  593.             tempFrameP->maskPort = maskGWorld;
  594.             tempFrameP->maskDevice = GetGWorldDevice( maskGWorld );
  595.             tempFrameP->maskPixHndl = GetGWorldPixMap( maskGWorld);
  596.         }
  597.         
  598.         tempFrameP->frameRect = *frameRect;
  599.         tempFrameP->sharesGWorld = true;
  600.         tempFrameP->isWindowFrame = false;
  601.         tempFrameP->numScanLines = numScanLines;
  602.  
  603.             // the useCount keeps track of the number of sprites that
  604.             // are using this frame. we need to know this so we don't
  605.             // dispose this frame twice when we are disposing the 
  606.             // sprites that use it.
  607.         tempFrameP->useCount = 0;
  608.  
  609.         SWInitializeFrame( tempFrameP );
  610.     }
  611.     else
  612.     {
  613.         err = MemError();
  614.     }
  615.  
  616.     if (err == noErr)
  617.     {
  618.             // make a region mask
  619.         if (((maskType & kRegionMask) != 0) && (err == noErr))
  620.         {
  621.             SW_ASSERT(maskGWorld != NULL);
  622.             
  623.             err = SWCreateRegionFromGWorldAndRectPartial(&maskRgn, maskGWorld, 
  624.                     tempMaskGWorld, frameRect);
  625.                 
  626.             if (err == noErr)
  627.             {
  628.                 SWSetFrameMaskRgn(tempFrameP, maskRgn);
  629.             }
  630.         }
  631.     
  632.         if (err == noErr)
  633.         {
  634.             *newFrameP = tempFrameP;
  635.         }
  636.         else
  637.         {
  638.                 // an error occurred so dispose of anything we managed to create
  639.                 
  640.             if (tempFrameP != NULL)
  641.             {
  642.                 SWDisposeFrame(&tempFrameP);
  643.             }
  644.         }
  645.     }
  646.     
  647.     SWSetStickyIfError( err );
  648.     return err;
  649. }
  650.  
  651.  
  652. ///--------------------------------------------------------------------------------------
  653. //    SWDisposeFrame
  654. ///--------------------------------------------------------------------------------------
  655.  
  656. SW_FUNC Boolean SWDisposeFrame(
  657.     FramePtr *oldFramePP)
  658. {
  659.     Boolean        frameDisposed;
  660.     FramePtr    oldFrameP = *oldFramePP;
  661.  
  662.     frameDisposed = false;
  663.     if (oldFrameP != NULL)
  664.     {
  665.         SW_ASSERT( !oldFrameP->isWindowFrame );
  666.  
  667.             // is this frame still in use by another sprite?
  668.         if (oldFrameP->useCount > 1)
  669.         {
  670.                 // one less sprite is using it now!
  671.             oldFrameP->useCount--;
  672.         }
  673.         else    // no more sprites are using this frame
  674.         {    
  675.             frameDisposed = true;
  676.             if (oldFrameP->framePort != NULL)
  677.             {
  678.                 if ( !oldFrameP->sharesGWorld )
  679.                     DisposeGWorld(oldFrameP->framePort);
  680.                 oldFrameP->framePort = NULL;
  681.                 oldFrameP->frameDevice = NULL;
  682.                 oldFrameP->framePixHndl = NULL;
  683.             }
  684.             
  685.             if (oldFrameP->maskRgn != NULL)
  686.             {
  687.                 DisposeRgn(oldFrameP->maskRgn);
  688.                 oldFrameP->maskRgn = NULL;
  689.             }
  690.             
  691.             if (oldFrameP->maskPort != NULL)
  692.             {
  693.                 if ( !oldFrameP->sharesGWorld )
  694.                     DisposeGWorld(oldFrameP->maskPort);
  695.                 oldFrameP->maskPort = NULL;
  696.                 oldFrameP->maskDevice = NULL;
  697.                 oldFrameP->maskPixHndl = NULL;
  698.             }
  699.  
  700.         #if SW_68K
  701.             if (oldFrameP->pixCodeH != NULL)
  702.             {
  703.                 DisposeHandle((Handle)oldFrameP->pixCodeH);
  704.                 oldFrameP->pixCodeH = NULL;
  705.                 oldFrameP->frameBlitterP = NULL;
  706.             }
  707.         #endif
  708.         
  709.             DisposePtr((Ptr)oldFrameP);
  710.             *oldFramePP = NULL;    // Change the original pointer to NULL
  711.         }
  712.     }
  713.     
  714.     return frameDisposed;
  715. }
  716.  
  717.  
  718. ///--------------------------------------------------------------------------------------
  719. //    SWDisposeWindowFrame
  720. ///--------------------------------------------------------------------------------------
  721.  
  722. SW_FUNC void SWDisposeWindowFrame(
  723.     FramePtr *oldFramePP)
  724. {
  725.     FramePtr    oldFrameP = *oldFramePP;
  726.     
  727.     if (oldFrameP != NULL)
  728.     {
  729.         SW_ASSERT( oldFrameP->isWindowFrame );
  730.  
  731.         DisposePtr((Ptr)oldFrameP);
  732.         *oldFramePP = NULL;    // Change the original pointer to NULL
  733.     }
  734. }
  735.  
  736. #pragma mark -
  737.  
  738. ///--------------------------------------------------------------------------------------
  739. //    SWSetPortToFrame
  740. ///--------------------------------------------------------------------------------------
  741.  
  742. SW_FUNC void SWSetPortToFrame(
  743.     FramePtr dstFrameP)
  744. {
  745.     SW_ASSERT(dstFrameP != NULL);
  746.     SW_ASSERT(dstFrameP->framePort != NULL);
  747.     SW_ASSERT(dstFrameP->isFrameLocked);
  748.  
  749.     SetGWorld( dstFrameP->framePort, dstFrameP->frameDevice );
  750. }
  751.  
  752.  
  753. ///--------------------------------------------------------------------------------------
  754. //    SWAlignFrameToWindow
  755. ///--------------------------------------------------------------------------------------
  756.  
  757. SW_FUNC Boolean SWAlignFrameToWindow(
  758.     FramePtr dstFrameP,
  759.     FramePtr windowFrameP)
  760. {
  761.     Rect            globalRect;
  762.     GWorldPtr        newGWorld;
  763.     GWorldFlags        flags;
  764.     Boolean            wasLocked;
  765.     GWorldPtr        oldGWorld;
  766.     GDHandle        oldDevice;
  767.     Boolean            wasCurrent;
  768.     OSErr            err;
  769.     Boolean            redraw = false;
  770.     
  771.     SW_ASSERT(windowFrameP != NULL);
  772.     SW_ASSERT(windowFrameP->isWindowFrame);
  773.     SW_ASSERT(dstFrameP != NULL);
  774.     SW_ASSERT(!dstFrameP->isWindowFrame);
  775.         
  776.     if ( dstFrameP->framePort != NULL &&
  777.          windowFrameP->framePort != NULL &&
  778.          dstFrameP->frameDepth == windowFrameP->frameDepth )
  779.     {
  780.         GetGWorld( &oldGWorld, &oldDevice );
  781.         newGWorld = dstFrameP->framePort;
  782.         
  783.         wasCurrent = (newGWorld == oldGWorld);
  784.         SetPort( (GrafPtr) windowFrameP->framePort);
  785.         
  786.         globalRect = dstFrameP->framePort->portRect;
  787.         LocalToGlobal( &topLeft(globalRect) );
  788.         LocalToGlobal( &botRight(globalRect) );
  789.         
  790.         wasLocked = dstFrameP->isFrameLocked;
  791.         if ( wasLocked )
  792.             SWUnlockFrame( dstFrameP );
  793.             
  794.         flags = UpdateGWorld( &newGWorld, 0, &globalRect,
  795.                         (CTabHandle) NULL, (GDHandle) NULL, (GWorldFlags) 0  );
  796.     
  797.         if ( !(flags & gwFlagErr) )
  798.         {
  799.             dstFrameP->framePort = newGWorld;
  800.             dstFrameP->framePixHndl = GetGWorldPixMap( newGWorld );
  801.             dstFrameP->frameDevice = GetGWorldDevice( newGWorld );
  802.             
  803.             SetPort( (GrafPtr) newGWorld);
  804.             SetOrigin(0,0);
  805.             
  806.                 // did we have to change anything ?
  807.             if ( flags & (reallocPix | newDepth | newRowBytes) )
  808.             {
  809.                 SWInitializeFrame( dstFrameP );
  810.             }
  811.             if ( flags & (reallocPix | newDepth | mapPix) )
  812.             {
  813.                 redraw = true;
  814.             }
  815.         }
  816.         else
  817.             err = (QDErr) flags;
  818.         
  819.         if ( wasLocked )
  820.             SWLockFrame( dstFrameP );
  821.         
  822.         if ( wasCurrent )
  823.             SWSetPortToFrame( dstFrameP );
  824.         else
  825.             SetGWorld( oldGWorld, oldDevice );
  826.     }
  827.     
  828.     return redraw;
  829. }
  830.  
  831.  
  832. ///--------------------------------------------------------------------------------------
  833. //    SWInitializeFrame
  834. ///--------------------------------------------------------------------------------------
  835.  
  836. SW_FUNC void SWInitializeFrame(
  837.     FramePtr tempFrameP )
  838. {
  839.     long                 curScanLine;
  840.     long                rowOffset;
  841.     short                 depth;
  842.     PixMapHandle         pixmap;
  843.  
  844.     SW_ASSERT(tempFrameP != NULL);
  845.     SW_ASSERT(tempFrameP->framePixHndl != NULL);
  846.     SW_ASSERT(tempFrameP->frameDepth != 0);
  847.     
  848. //    Note: do NOT set the useCount in this function,
  849. //    since it might be called again if we need to change depth/rowbytes for some reason...
  850.     
  851.     pixmap = tempFrameP->framePixHndl;
  852.     depth = tempFrameP->frameDepth;
  853.     
  854.         // cache pixmap info for use by our blitter routine
  855.     tempFrameP->frameRowBytes = SWGetPixRowBytes( pixmap );
  856.  
  857.         // this calculation generates a mask value that we use to
  858.         // long word align the rectangle when we draw the frame.
  859.         // note that the expression "sizeof(long) * kBitsPerByte" gives us
  860.         // the number of bits in a long.     <-- that ought to always be 32... --afb    
  861.  
  862.         // align on long word (4-byte) boundary:
  863.     tempFrameP->rightAlignFactor = (32 / depth) - 1;
  864.     tempFrameP->leftAlignFactor = ~(tempFrameP->rightAlignFactor);
  865.     
  866.         // calculate amount to leftshift pixels to get bytes (works for depths >= 8)
  867.     tempFrameP->pixelShift = depth >> 4;
  868.  
  869.         // here we set up an array of offsets to the scan lines of
  870.         // this frame. this allows us to address a particular scan line
  871.         // without doing a costly multiply.        <-- costly on the 68k, that is --afb
  872.     
  873.         // (array data follows right after the frame struct)
  874.     tempFrameP->scanLinePtrArray = (unsigned long*) (tempFrameP + 1);
  875.     
  876.     rowOffset = (long) tempFrameP->frameRect.top * tempFrameP->frameRowBytes;
  877.     for (curScanLine = 0; curScanLine < tempFrameP->numScanLines; curScanLine++)
  878.     {
  879.         tempFrameP->scanLinePtrArray[curScanLine] = rowOffset;
  880.         rowOffset += tempFrameP->frameRowBytes;
  881.     }
  882.         
  883. }
  884.  
  885. ///--------------------------------------------------------------------------------------
  886. //    SWSetFrameMaskRgn
  887. ///--------------------------------------------------------------------------------------
  888.  
  889. SW_FUNC void SWSetFrameMaskRgn(
  890.     FramePtr srcFrameP,
  891.     RgnHandle maskRgn)
  892. {
  893.     SW_ASSERT(srcFrameP != NULL);
  894.     SW_ASSERT(maskRgn != NULL);
  895.     
  896.     if (maskRgn != NULL)
  897.     {
  898.         srcFrameP->maskRgn = maskRgn;
  899.     
  900.         srcFrameP->offsetPoint.h = (**maskRgn).rgnBBox.left;
  901.         srcFrameP->offsetPoint.v = (**maskRgn).rgnBBox.top;
  902.     }
  903. }
  904.  
  905.  
  906. ///--------------------------------------------------------------------------------------
  907. //    SWSetFrameHotSpot
  908. ///--------------------------------------------------------------------------------------
  909.  
  910. SW_FUNC void SWSetFrameHotSpot(
  911.     FramePtr srcFrameP,
  912.     short hotSpotH,
  913.     short hotSpotV)
  914. {
  915.     SW_ASSERT(srcFrameP != NULL);
  916.     
  917.     srcFrameP->hotSpotH = hotSpotH;
  918.     srcFrameP->hotSpotV = hotSpotV;
  919. }
  920.  
  921.  
  922. ///--------------------------------------------------------------------------------------
  923. //    SWSetFrameCollisionInset
  924. ///--------------------------------------------------------------------------------------
  925.  
  926. SW_FUNC void SWSetFrameCollisionInset(
  927.     FramePtr srcFrameP,
  928.     short leftInset,
  929.     short topInset,
  930.     short rightInset,
  931.     short bottomInset)
  932. {
  933.     SW_ASSERT(srcFrameP != NULL);
  934.     
  935.     if (leftInset == 0 && topInset == 0 && rightInset == 0 && bottomInset == 0)
  936.         srcFrameP->usesCollisionInset = false;
  937.     else
  938.         srcFrameP->usesCollisionInset = true;
  939.     
  940.     SW_SET_RECT(srcFrameP->collisionInset, leftInset, topInset, rightInset, bottomInset)
  941. }
  942.  
  943.  
  944. ///--------------------------------------------------------------------------------------
  945. //    SWSetFrameInterlacingMode
  946. ///--------------------------------------------------------------------------------------
  947.  
  948. SW_FUNC void SWSetFrameInterlacingMode(
  949.     FramePtr dstFrameP,
  950.     Boolean skipEveryOtherLine,
  951.     Boolean skipOddLines)
  952. {
  953.     SW_ASSERT(dstFrameP != NULL);
  954.     
  955.     dstFrameP->interlacingIsOn = skipEveryOtherLine;
  956.     dstFrameP->skipOddLines = skipOddLines;
  957. }
  958.  
  959.  
  960. ///--------------------------------------------------------------------------------------
  961. //  SWCopyFrame - creates a new Frame and copies oldFrameP into it.
  962. ///--------------------------------------------------------------------------------------
  963.  
  964. SW_FUNC OSErr SWCopyFrame(
  965.     SpriteWorldPtr destSpriteWorldP,
  966.     FramePtr oldFrameP, 
  967.     FramePtr *newFrameP,
  968.     Boolean copyMasks)
  969. {
  970.     OSErr             err;  
  971.     GWorldPtr         saveGWorld;
  972.     GDHandle         saveGDH;
  973.     GDHandle        theGDH;
  974.     GWorldFlags        pixelState;
  975.     short            depth;
  976.     FramePtr         tempFrameP;
  977.     Rect             frameRect;
  978.     
  979.     SW_ASSERT(newFrameP != NULL);
  980.     SW_ASSERT(oldFrameP != NULL);
  981.     SW_ASSERT(oldFrameP->framePort != NULL);
  982.     SW_ASSERT(destSpriteWorldP != NULL);
  983.  
  984.     *newFrameP = NULL;
  985.     tempFrameP = NULL;
  986.     depth = destSpriteWorldP->pixelDepth;
  987.     theGDH = destSpriteWorldP->mainSWGDH;
  988.  
  989.     GetGWorld(&saveGWorld, &saveGDH);
  990.     
  991.         // Get size of new frame
  992.     frameRect = oldFrameP->frameRect;
  993.     OffsetRect(&frameRect, -frameRect.left, -frameRect.top);
  994.     
  995.         // Create the new frame
  996.     err = SWCreateFrame(theGDH, &tempFrameP, &frameRect, depth, kCreateGWorld);
  997.     
  998.         // Copy the image from the old frame into the new frame
  999.     if ( err == noErr )
  1000.     {
  1001.         pixelState = GetPixelsState( oldFrameP->framePixHndl );
  1002.         (void)LockPixels( GetGWorldPixMap(oldFrameP->framePort) );
  1003.         (void)LockPixels( GetGWorldPixMap(tempFrameP->framePort) );
  1004.         SetGWorld( oldFrameP->framePort, nil ); ForeColor( blackColor ); BackColor( whiteColor );
  1005.         SetGWorld( tempFrameP->framePort, nil );
  1006.  
  1007.         CopyBits ( (BitMap*)*GetGWorldPixMap( oldFrameP->framePort ),
  1008.             (BitMap*)*GetGWorldPixMap( tempFrameP->framePort ),
  1009.             &oldFrameP->frameRect, 
  1010.             &frameRect, 
  1011.             srcCopy, 
  1012.             nil);
  1013.  
  1014.             // Restore oldFrameP to its previous locked/unlocked state.
  1015.         SetPixelsState( oldFrameP->framePort->portPixMap, pixelState );
  1016.         
  1017.             // Unlock our tempFrameP.
  1018.         UnlockPixels( GetGWorldPixMap(tempFrameP->framePort) );
  1019.     }
  1020.  
  1021.     
  1022.         // copy region mask
  1023.     if ((oldFrameP->maskRgn != NULL) && (err == noErr))
  1024.     {
  1025.         tempFrameP->maskRgn = NewRgn();
  1026.     
  1027.         if (tempFrameP->maskRgn == NULL)
  1028.             err = MemError();
  1029.         else if (copyMasks)
  1030.             CopyRgn(oldFrameP->maskRgn, tempFrameP->maskRgn);
  1031.     }
  1032.  
  1033.         // copy pixel mask
  1034.     if ((oldFrameP->maskPort != NULL) && (err == noErr))
  1035.     {
  1036.         if ( SWGetPixBitDepth((**theGDH).gdPMap) == depth )
  1037.             err = NewGWorld( &tempFrameP->maskPort, depth, &frameRect, nil, theGDH, noNewDevice );
  1038.         else
  1039.             err = NewGWorld( &tempFrameP->maskPort, depth, &frameRect, nil, nil, 0 );
  1040.  
  1041.             // Copy pixel mask from old frame into new frame
  1042.         if ((err == noErr) && (copyMasks))
  1043.         {
  1044.             tempFrameP->maskDevice = GetGWorldDevice( tempFrameP->maskPort );
  1045.             tempFrameP->maskPixHndl = GetGWorldPixMap( tempFrameP->maskPort );
  1046.  
  1047.             pixelState = GetPixelsState( oldFrameP->maskPixHndl );
  1048.             (void)LockPixels( oldFrameP->maskPixHndl );
  1049.             (void)LockPixels( tempFrameP->maskPixHndl );
  1050.             SetGWorld( oldFrameP->maskPort, nil );
  1051.             ForeColor( blackColor );
  1052.             BackColor( whiteColor );
  1053.             SetGWorld( tempFrameP->maskPort, nil );
  1054.     
  1055.             CopyBits( (BitMap*) *oldFrameP->maskPixHndl,
  1056.                 (BitMap*) *tempFrameP->maskPixHndl,
  1057.                 &oldFrameP->frameRect, 
  1058.                 &frameRect, 
  1059.                 srcCopy, 
  1060.                 nil);
  1061.     
  1062.                 // Restore oldFrameP to its previous locked/unlocked state.
  1063.             SetPixelsState( oldFrameP->maskPixHndl, pixelState );
  1064.             
  1065.                 // Unlock our tempFrameP. 
  1066.             UnlockPixels( tempFrameP->maskPixHndl );
  1067.         }
  1068.     }
  1069.  
  1070.     if (err == noErr)
  1071.     {
  1072.         *newFrameP = tempFrameP;
  1073.     }
  1074.     else
  1075.     {
  1076.             // an error occurred so dispose of anything we managed to create
  1077.         if (tempFrameP != NULL)
  1078.         {
  1079.             SWDisposeFrame(&tempFrameP);
  1080.         }
  1081.     }
  1082.  
  1083.     SetGWorld(saveGWorld, nil);
  1084.  
  1085.     SWSetStickyIfError( err );
  1086.     return err;
  1087. }
  1088.  
  1089.  
  1090. ///--------------------------------------------------------------------------------------
  1091. //    SWUpdateFrameMasks - updates the pixel and region masks of a frame, from the frame image
  1092. ///--------------------------------------------------------------------------------------
  1093.  
  1094. SW_FUNC OSErr SWUpdateFrameMasks(
  1095.     FramePtr srcFrameP)
  1096. {
  1097.     RGBColor            oldTransparentColor, myBlackColor;
  1098.     Boolean                frameWasUnlocked = false;
  1099.     short                depth;
  1100.     OSErr                err = noErr;
  1101.  
  1102.     SW_ASSERT(srcFrameP != NULL);
  1103.     
  1104.     if (!srcFrameP->isFrameLocked)
  1105.     {
  1106.         SWLockFrame(srcFrameP);
  1107.         frameWasUnlocked = true;
  1108.     }
  1109.     
  1110.     depth = srcFrameP->frameDepth;
  1111.     
  1112.         // If there is a pixel mask...
  1113.     if (srcFrameP->maskPort != NULL)
  1114.     {
  1115.         SW_ASSERT(srcFrameP->framePort != NULL);
  1116.         
  1117.             // We must set the transparent color to black before re-creating the mask
  1118.             // if we are in 16-bits or above, since the image GWorld will have been "fixed".
  1119.         if (depth > 8)
  1120.         {
  1121.             oldTransparentColor = gSWTransparentColor;
  1122.             myBlackColor.red = myBlackColor.green = myBlackColor.blue = 0;
  1123.             SWSetTransparentColor(&myBlackColor);
  1124.         }
  1125.         
  1126.             // Recreate the pixel mask
  1127.         SWCreatePixelMaskFromGWorld( srcFrameP->framePort, srcFrameP->maskPort, &srcFrameP->frameRect );
  1128.         
  1129.         if (depth > 8)
  1130.             SWSetTransparentColor(&oldTransparentColor);
  1131.         
  1132.             // Recreate the region mask if there is one.
  1133.         if (srcFrameP->maskRgn != NULL)
  1134.         {
  1135.             DisposeRgn( srcFrameP->maskRgn );
  1136.             
  1137.                 // the pixel mask has inverted colors if in indexed mode
  1138.             if (depth <= 8)
  1139.                 SWInvertRect(srcFrameP->maskPort, &srcFrameP->frameRect);
  1140.             
  1141.             err = SWCreateRegionFromGWorldAndRect( &srcFrameP->maskRgn,
  1142.                 srcFrameP->maskPort, &srcFrameP->frameRect );
  1143.             
  1144.             if (err == noErr)
  1145.                 SWSetFrameMaskRgn(srcFrameP, srcFrameP->maskRgn);
  1146.             
  1147.             if (depth <= 8)
  1148.                 SWInvertRect(srcFrameP->maskPort, &srcFrameP->frameRect);
  1149.         }
  1150.     }
  1151.     else if (srcFrameP->maskRgn != NULL)
  1152.     {
  1153.             // In case there is a region mask but no pixel mask...
  1154.         err = SWCreateRegionMaskFromGWorld( srcFrameP->framePort,
  1155.                     &srcFrameP->frameRect, srcFrameP->maskRgn );
  1156.         
  1157.         if (err == noErr)
  1158.             SWSetFrameMaskRgn(srcFrameP, srcFrameP->maskRgn);
  1159.     }
  1160.     
  1161. //    if (srcFrameP->rleDataH != NULL && srcFrameP->framePort != NULL)
  1162.         // Looks like we can't re-create RLE data for a single frame.
  1163.     
  1164. #if SW_68K
  1165.     if (srcFrameP->pixCodeH != NULL)
  1166.         SWCompileFrame(srcFrameP);
  1167. #endif
  1168.     
  1169.     if (frameWasUnlocked)
  1170.         SWUnlockFrame(srcFrameP);
  1171.  
  1172.     SWSetStickyIfError( err );
  1173.     return err;
  1174. }
  1175.  
  1176.  
  1177. ///--------------------------------------------------------------------------------------
  1178. //    SWLockFrame
  1179. ///--------------------------------------------------------------------------------------
  1180.  
  1181. SW_FUNC void SWLockFrame(
  1182.     FramePtr srcFrameP)
  1183. {
  1184.     PixMapHandle         pixMapH;
  1185.     long                offsetX,offsetY;
  1186.     
  1187.     SW_ASSERT(srcFrameP != NULL);
  1188.     SW_ASSERT(!srcFrameP->isWindowFrame);
  1189.  
  1190.     if (!srcFrameP->isFrameLocked)
  1191.     {
  1192.         srcFrameP->isFrameLocked = true;
  1193.         
  1194.         if (srcFrameP->framePort != NULL)
  1195.         {
  1196.             SW_ASSERT(srcFrameP->framePixHndl != NULL);
  1197.  
  1198.             pixMapH = srcFrameP->framePixHndl;
  1199.             (void)LockPixels( pixMapH );
  1200.             HLockHi( (Handle)pixMapH );
  1201.             srcFrameP->framePix = (PixMapPtr)StripAddress( *(Handle)pixMapH );
  1202.             
  1203.             srcFrameP->frameBaseAddr = SWGetPixBaseAddr( pixMapH );
  1204.             srcFrameP->frameRowBytes = SWGetPixRowBytes( pixMapH );
  1205.             srcFrameP->frameDepth = SWGetPixBitDepth( pixMapH );
  1206.     
  1207.             offsetX = - (**pixMapH).bounds.left;
  1208.             offsetY = - (**pixMapH).bounds.top;
  1209.     
  1210.                 // calculate start of pixmap
  1211.             if ( offsetX != 0 || offsetY != 0 )
  1212.             {
  1213.                 srcFrameP->frameBaseAddr +=  offsetY * srcFrameP->frameRowBytes;
  1214.                 srcFrameP->frameBaseAddr += (offsetX * srcFrameP->frameDepth) >> 3;
  1215.             }
  1216.             
  1217.                 // calculate pixel offset, in case a pixel is less than a whole byte
  1218.             if ( srcFrameP->frameDepth < 8 )
  1219.             {
  1220.                 short         pixelStart;
  1221.                 short        roundOff;
  1222.             
  1223.                     // note: don't forget the pixmap bounds here, in case it's been justified for alignment
  1224.                 pixelStart = -(**pixMapH).bounds.left;
  1225.                 roundOff = 8 / srcFrameP->frameDepth;
  1226.                 
  1227.                 srcFrameP->worldRectOffset = pixelStart % roundOff;
  1228.             }
  1229.             else
  1230.                 srcFrameP->worldRectOffset = 0;
  1231.  
  1232.         }
  1233.                 
  1234.         if (srcFrameP->maskPort != NULL)
  1235.         {
  1236.             SW_ASSERT(srcFrameP->maskPixHndl != NULL);
  1237.  
  1238.             pixMapH = srcFrameP->maskPixHndl;
  1239.             (void)LockPixels( pixMapH );
  1240.             HLockHi( (Handle)pixMapH );
  1241.             srcFrameP->maskPix = (PixMapPtr)StripAddress( *(Handle)pixMapH );
  1242.             
  1243.             srcFrameP->maskBaseAddr = SWGetPixBaseAddr( pixMapH );
  1244.             
  1245.             // assume mask has bounds w. topLeft(0,0) since we never align frames with masks ?
  1246.         }
  1247.  
  1248.     #if SW_68K
  1249.         if (srcFrameP->pixCodeH != NULL)
  1250.         {
  1251.             HLockHi((Handle)srcFrameP->pixCodeH);
  1252.             srcFrameP->frameBlitterP = (CompiledPtr) StripAddress( *(Handle)srcFrameP->pixCodeH );
  1253.         }
  1254.     #endif
  1255.  
  1256.     }
  1257. }
  1258.  
  1259.  
  1260. ///--------------------------------------------------------------------------------------
  1261. //    SWUnlockFrame
  1262. ///--------------------------------------------------------------------------------------
  1263.  
  1264. SW_FUNC void SWUnlockFrame(
  1265.     FramePtr srcFrameP)
  1266. {
  1267.     SW_ASSERT(srcFrameP != NULL);
  1268.     SW_ASSERT(!srcFrameP->isWindowFrame);
  1269.     
  1270.     if (srcFrameP->isFrameLocked)
  1271.     {
  1272.         srcFrameP->isFrameLocked = false;
  1273.         
  1274.         if (srcFrameP->framePort != NULL && srcFrameP->framePixHndl != NULL)
  1275.         {
  1276.             HUnlock( (Handle)srcFrameP->framePixHndl );
  1277.             UnlockPixels(srcFrameP->framePixHndl);
  1278.         }
  1279.  
  1280.         srcFrameP->framePix = NULL;
  1281.         srcFrameP->frameBaseAddr = NULL;
  1282.         
  1283.         if (srcFrameP->maskPort != NULL && srcFrameP->maskPixHndl != NULL)
  1284.         {
  1285.             HUnlock( (Handle)srcFrameP->maskPixHndl );
  1286.             UnlockPixels(srcFrameP->maskPixHndl);
  1287.         }
  1288.  
  1289.         srcFrameP->maskPix = NULL;
  1290.         srcFrameP->maskBaseAddr = NULL;
  1291.         
  1292.     #if SW_68K
  1293.         if (srcFrameP->pixCodeH != NULL)
  1294.         {
  1295.             HUnlock((Handle)srcFrameP->pixCodeH);
  1296.             srcFrameP->frameBlitterP = NULL;
  1297.         }
  1298.     #endif
  1299.     }
  1300. }
  1301.  
  1302.  
  1303. ///--------------------------------------------------------------------------------------
  1304. //    SWLockWindowFrame
  1305. ///--------------------------------------------------------------------------------------
  1306.  
  1307. SW_FUNC void SWLockWindowFrame(
  1308.     FramePtr windowFrameP)
  1309. {
  1310.     GrafPtr                savePort;
  1311.     Rect                globalRect;
  1312.     PixMapHandle         pixMapH;
  1313.     GDHandle            maxDevice;
  1314.     long                offsetX,offsetY;
  1315.     
  1316.     SW_ASSERT(windowFrameP != NULL);
  1317.     SW_ASSERT(windowFrameP->framePort != NULL);
  1318.     SW_ASSERT(windowFrameP->framePixHndl != NULL);
  1319.     SW_ASSERT(windowFrameP->isWindowFrame);
  1320.  
  1321.     if (!windowFrameP->isFrameLocked)
  1322.     {
  1323.         windowFrameP->isFrameLocked = true;
  1324.         pixMapH = windowFrameP->framePixHndl;
  1325.         HLockHi( (Handle)pixMapH );
  1326.         windowFrameP->framePix = (PixMapPtr)StripAddress( *pixMapH );
  1327.         
  1328.         // note: windowFrameP->frameDevice is ALWAYS MainDevice !
  1329.         //       windowFrameP->framePixHndl is ALWAYS a PixMap on MainDevice (but with different bounds)
  1330.         //         (so neither of those will help us to get address for blitter... )
  1331.         
  1332.             // get global frame rect
  1333.         GetPort( &savePort );
  1334.         SetPort( (GrafPtr) windowFrameP->framePort );
  1335.         globalRect = windowFrameP->framePort->portRect;
  1336.         LocalToGlobal(&topLeft(globalRect));
  1337.         LocalToGlobal(&botRight(globalRect));
  1338.         SetPort( savePort );
  1339.             
  1340.             // determine which device to use (deepest intersecting)
  1341.         maxDevice = GetMaxDevice( &globalRect );
  1342.         pixMapH = (**maxDevice).gdPMap;
  1343.         
  1344.         windowFrameP->frameBaseAddr = SWGetPixBaseAddr( pixMapH );
  1345.         windowFrameP->frameRowBytes = SWGetPixRowBytes( pixMapH );
  1346.         windowFrameP->frameDepth = SWGetPixBitDepth( pixMapH );
  1347.     
  1348.             // calculate start of window on device
  1349.         offsetX = globalRect.left - (**maxDevice).gdRect.left;
  1350.         offsetY = globalRect.top - (**maxDevice).gdRect.top;
  1351.         
  1352.             // calculate start of pixmap bounds
  1353.         offsetX -= (**pixMapH).bounds.left;
  1354.         offsetY -= (**pixMapH).bounds.top;
  1355.         
  1356.         if ( offsetX != 0 || offsetY != 0 )
  1357.         {
  1358.             windowFrameP->frameBaseAddr += offsetY * windowFrameP->frameRowBytes;
  1359.             windowFrameP->frameBaseAddr += (offsetX *  windowFrameP->frameDepth) >> 3;
  1360.         }
  1361.         
  1362.             // calculate pixel offset, in case a pixel is less than a whole byte
  1363.         if ( windowFrameP->frameDepth < 8 )
  1364.         {
  1365.                 short         pixelStart;
  1366.                 short        roundOff;
  1367.                 
  1368.                 pixelStart = offsetX;
  1369.                 roundOff = 8 / windowFrameP->frameDepth;
  1370.                 
  1371.                 windowFrameP->worldRectOffset = pixelStart % roundOff;
  1372.         }
  1373.         else
  1374.             windowFrameP->worldRectOffset = 0;
  1375.         
  1376.         SWInitializeFrame(windowFrameP);
  1377.     }
  1378. }
  1379.  
  1380.  
  1381. ///--------------------------------------------------------------------------------------
  1382. //    SWUnlockWindowFrame
  1383. ///--------------------------------------------------------------------------------------
  1384.  
  1385. SW_FUNC void SWUnlockWindowFrame(
  1386.     FramePtr windowFrameP)
  1387. {
  1388.     SW_ASSERT(windowFrameP != NULL);
  1389.     SW_ASSERT(windowFrameP->isWindowFrame);
  1390.     
  1391.     if (windowFrameP->isFrameLocked)
  1392.     {
  1393.         windowFrameP->isFrameLocked = false;
  1394.         HUnlock( (Handle)windowFrameP->framePixHndl );
  1395.         windowFrameP->framePix = NULL;
  1396.         windowFrameP->frameBaseAddr = NULL;
  1397.     }
  1398. }
  1399.  
  1400.